package common.server.redis;

import java.util.*;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import common.server.exception.BaseException;
import common.server.utils.JsonUtils;

/**
 * @author Administrator
 * @version [版本号, 2017/11/22 0022]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public abstract class AbstractRedisResource<E>
		implements RedisResource<E>, CloseResource {

	private static final Logger logger = LoggerFactory
			.getLogger(AbstractRedisResource.class);

	@Override
	public <T> Map<String, T> hgetAll(String key, Class<T> clazz) {
		Map<String, String> result = hgetAll(key);
		if (result.isEmpty()) {
			return Collections.emptyMap();
		}
		Map<String, T> newMap = new HashMap<>(result.size());
		result.forEach((k, v) -> newMap.put(k, JsonUtils.fromJson(v, clazz)));
		return newMap;
	}

	@Override
	public void set(String key, Object value, long time) {
		set(key, JsonUtils.toJson(value), time);
	}

	@Override
	public void hmset(String key, Map<String, String> hash) {
		hmset(key, hash, 0);
	}

	@Override
	public void hset(String key, String field, Object value, long time) {
		hset(key, field, JsonUtils.toJson(value), time);
	}

	@Override
	public void lpush(String key, Object value) {
		lpush(key, JsonUtils.toJson(value));
	}

	@Override
	public void rpush(String key, Object value) {
		rpush(key, JsonUtils.toJson(value));
	}

	/**
	 * @param value
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	protected <T> List<T> toList(Collection<String> value, Class<T> clazz) {
		if (value != null) {
			if (clazz == String.class) {
				return (List<T>) new ArrayList<>(value);
			}
			List<T> newValue = new ArrayList<>();
			for (String temp : value) {
				newValue.add(JsonUtils.fromJson(temp, clazz));
			}
			return newValue;
		}
		return null;
	}

	/**
	 *
	 * @param function
	 * @param <R>
	 * @return
	 */
	protected <R> R call(Function<E, R> function) {
		long s = System.currentTimeMillis();
		try {
			R r = function.apply(getRealResource());
			logger.debug("Execute Redis Command Result:{}", r);
			return r;
		} catch (Exception e) {
			logger.error("Execute Redis Command Error:", e);
			throw new BaseException(e.getMessage());
		} finally {
			// 释放资源
			close();
			logger.debug("Execute call method use time:{}",
					System.currentTimeMillis() - s);
		}

	}
}
